package com.vms.control.weight.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

import android.content.Context;

import com.vms.NetLog;
import com.vms.Settings.ValueType;
import com.vms.control.weight.App;
import com.vms.control.weight.input.IValueChanged;
import com.vms.control.weight.input.InputSettingsFactory;
import com.vms.control.weight.model.DateModel.IOnDateChanged;
import com.vms.healthcontrol.WeightDataSource;
import com.vms.healthcontrol.ValueUnderControl;
import com.vms.healthcontrol.WeightDataSource.WeightSelectionBuilder;

public class DataBaseWrapper implements IOnDateChanged {

	private NetLog netLog = new NetLog("DataBaseWrapper");
	private WeightDataSource mDatabase;
	private DateModel mDateModel;
	
	public DataBaseWrapper(Collection<ValueType> controlValues, Context context, DateModel dateModel) {
		super();
		this.mDatabase = new WeightDataSource(context);
		this.mControlValues = controlValues;
		this.mDateModel = dateModel;
		this.mValues = new TreeMap<ValueType, ValueUnderControl>();
		
		this.mDateModel.registerDateChangeListener(this);
//		prepareControlValues();
	}
	
	public List<ValueUnderControl> getValuesForSelectedDate() {
		for (ValueType type : mControlValues) {
			return mDatabase.select(new WeightSelectionBuilder(
					ValueUnderControl.getDateLongStrForDb(mDateModel.getDate()),
					ValueUnderControl.getDateLongStrForDb(mDateModel.getDate()),
					Arrays.asList(new String[] {type.mName})));
		}
		throw new RuntimeException("Not found control values");
	}
	
//	private void prepareControlValues() {
//		for (ValueType type : mControlValues) {
//			List<ValueUnderControl> list = mDatabase.selectByNameAndDate(type.mName,
//					ValueUnderControl.getDateLongStrForDb( mDateModel.getDate()));
//			
//			//mDatabase.rowsByDate(mDateModel.getDate());
//			ValueUnderControl value = null;
//			
//			if(list.isEmpty()) {
//				 value = ValueUnderControl.create(new InputSettingsFactory(type));
//				netLog.d("Prepare DEFAULT value: %s", value.toString());
//				
//			} else {
//				value = list.get(0); 
//				value.setModifiedInSession(value.getDbDate()
//						.equals(ValueUnderControl.getDateLongStrForDb(mDateModel.getDate())) );
//				netLog.d("Prepare from DB value: %s", value.toString());
//			}
//			mValues.put(type, value);
//			value.setModify(mDateModel.getDate());
//			
//		}
//	}

	private Collection<ValueType> mControlValues;
	private Map<ValueType,ValueUnderControl> mValues;
	
	
	public void saveControlValues () {
		
		Collection<String> typesToDelete = new ArrayList<String>();
		for (ValueType type : mValues.keySet()) {
			typesToDelete.add(type.mName);
		}
		
		String deleteDay = ValueUnderControl.getDateLongStrForDb(mDateModel.getDate());
		WeightSelectionBuilder selection = new WeightSelectionBuilder(deleteDay,deleteDay,typesToDelete);
		int deleted = mDatabase.delete(selection);
		netLog.d("BEFORE INSERT delete %d rows by date %s [%s]", deleted, deleteDay, selection.toString());
		
		for (ValueType type : mValues.keySet()) {
			ValueUnderControl newValue = mValues.get(type);
			// now save by button OK
//			if(!newValue.isModifiedInSession())
//				continue;
			newValue.setModify(mDateModel.getDate());
			mDatabase.insert(newValue);
			netLog.d("INSERT value: %s", mValues.get(type).toString());
		}
	}
	
	public CharSequence getValue(ValueType type) {
		return String.format(Locale.UK,"%.1f", mValues.get(type).getValue());
	}

	public CharSequence getCurrentDimensionFor(ValueType type) {
		return mValues.get(type).getShowDimension();
	}

	public void increaseValue(ValueType type) {
		mValues.get(type).increase();
		netLog.d("Increase value: %s", mValues.get(type).toString());
		notifyOnValueChangeListener();
	}

	public void decreaseValue(ValueType type) {
		mValues.get(type).decrease();
		netLog.d("Decrease value: %s", mValues.get(type).toString());
		notifyOnValueChangeListener();
	}
	
	public void setValue (ValueType type, float value) {
		mValues.get(type).set(value, mDateModel.getDate());
	}

	
	private Collection<IValueChanged> mValueChangeListeners = new ArrayList<IValueChanged>();
	
	public void registerOnValueChangeListener(IValueChanged listener) {
		if( mValueChangeListeners.contains(listener) )
			return;
		mValueChangeListeners.add(listener);
	}
	
	public void removeOnValueChangeListener(IValueChanged listener) {
		mValueChangeListeners.remove(listener);
	}
	
	public void notifyOnValueChangeListener() {
//		netLog.d("OnValueChange  [ listeners: "+mValueChangeListeners.size()+" ]");
		for (IValueChanged listener : mValueChangeListeners) {
			listener.onValueChange();
		}
	}

	@Override
	public void onDateChanged(Date date, boolean isToday) {
		//prepareControlValues();
		//notifyOnValueChangeListener();
	}

	public int selectAll() {
		return mDatabase.getRowsCount();
	}

	public int deleteAll() {
		return mDatabase.deleteAll();
	}
}
